home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Framework / Sources / UClipboardMgr.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  14.0 KB  |  520 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UClipboardMgr.cp 
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UCLIPBOARDMGR__
  7. #include "UClipboardMgr.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UCOREERRORMGR__
  13. #include "UCoreErrorMgr.h"
  14. #endif
  15.  
  16. #ifndef __UCOREGLOBALS__
  17. #include "UCoreGlobals.h"
  18. #endif
  19.  
  20. #ifndef __UCOREUTILITIES__
  21. #include "UCoreUtilities.h"
  22. #endif
  23.  
  24. #ifndef __UDEPENDENCIES__
  25. #include "UDependencies.h"
  26. #endif
  27.  
  28. #ifndef __UDESKSCRAPVIEW__
  29. #include "UDeskScrapView.h"
  30. #endif
  31.  
  32. #ifndef __UDISPATCHER__
  33. #include "UDispatcher.h"
  34. #endif
  35.  
  36. #ifndef __UDOCUMENT__
  37. #include "UDocument.h"
  38. #endif
  39.  
  40. //    #ifndef __UERRORMGR__
  41. //    #include "UErrorMgr.h"
  42. //    #endif
  43.  
  44. #ifndef __UMACAPPGLOBALS__
  45. #include "UMacAppGlobals.h"
  46. #endif
  47.  
  48. //    #ifndef __UMACAPPUTILITIES__
  49. //    #include "UMacAppUtilities.h"
  50. //    #endif
  51.  
  52. #ifndef __UMEMORY__
  53. #include "UMemory.h"
  54. #endif
  55.  
  56. #ifndef __UMENUMGR__
  57. #include "UMenuMgr.h"
  58. #endif
  59.  
  60. #ifndef __UVIEWSERVER__
  61. #include "UViewServer.h"
  62. #endif
  63.  
  64. #ifndef __UWINDOW__
  65. #include "UWindow.h"
  66. #endif
  67.  
  68. // ANSI
  69.  
  70. #ifndef __STDIO__
  71. #include <stdio.h>
  72. #endif
  73.  
  74. TClipboardMgr* gClipboardMgr;                    // declared in interface
  75.  
  76.  
  77. //========================================================================================
  78. // CLASS TClipboardMgr
  79. //========================================================================================
  80. #undef Inherited
  81. #define Inherited TBehavior
  82.  
  83. #pragma segment MAInit
  84. MA_DEFINE_CLASS_M1(TClipboardMgr, Inherited);
  85.  
  86. //----------------------------------------------------------------------------------------
  87. // TClipboardMgr constructor
  88. //----------------------------------------------------------------------------------------
  89. #pragma segment MAInit
  90.  
  91. TClipboardMgr::TClipboardMgr()
  92. {
  93.     fClipContext = NULL; 
  94.     fClipView = NULL;
  95.     fClipWindow = NULL;
  96.     fClipOrphanage = NULL;
  97.     fGotClipType = FALSE;
  98.  
  99.     fOldScrapStuff.scrapSize = 0;
  100.     fOldScrapStuff.scrapHandle = NULL;
  101.     fOldScrapStuff.scrapCount = 0;
  102.     fOldScrapStuff.scrapState = 0;
  103.     fOldScrapStuff.scrapName = NULL;
  104.  
  105.     fNewScrapStuff = fOldScrapStuff;
  106. } // TClipboardMgr::TClipboardMgr
  107.  
  108. //----------------------------------------------------------------------------------------
  109. // TClipboardMgr destructor
  110. //----------------------------------------------------------------------------------------
  111. #pragma segment MADestructorRes
  112.  
  113. TClipboardMgr::~TClipboardMgr()
  114. {
  115. }
  116.  
  117. //----------------------------------------------------------------------------------------
  118. // TClipboardMgr::IClipboardMgr:
  119. //----------------------------------------------------------------------------------------
  120. #pragma segment MAInit
  121.  
  122. void TClipboardMgr::IClipboardMgr()
  123. {
  124.     this->IBehavior(kClipboardManager);    
  125.  
  126.     this->AbsorbScrapStuff();                            // get the initial state of the desk scrap 
  127.     gClipboardMgr = this;
  128. } // TClipboardMgr::IClipboardMgr
  129.  
  130. //----------------------------------------------------------------------------------------
  131. // TClipboardMgr::AboutToLoseControl:
  132. //----------------------------------------------------------------------------------------
  133. #pragma segment MAActivate
  134.  
  135. void TClipboardMgr::AboutToLoseControl(Boolean convertClipboard)
  136. {
  137.     if (convertClipboard)
  138.     {
  139.         this->Changed(mAboutToLoseControl,this);
  140.  
  141.         if ((fClipView != NULL) && (!fClipWrittenToDeskScrap))
  142.         {
  143.             long err = ZeroScrap();
  144.  
  145.             FailInfo fi;
  146.             Try(fi)
  147.             {
  148.                 fClipView->WriteToDeskScrap();
  149.                 fi.Success();
  150.             }
  151.             else    // Recover
  152.             {
  153. #if qDebugMsg
  154.                 fprintf(stderr,"Can't use clipboard data outside this app\n");
  155. #endif
  156.                 if (fi.message == 0)
  157.                     fi.message = messageExportClipFailed;
  158.                 if (gDispatcher)
  159.                     gDispatcher->ShowError(fi.error, fi.message);
  160.             }
  161.             fClipWrittenToDeskScrap = TRUE;
  162.             this->AbsorbScrapStuff();
  163.         }
  164.     }
  165. } // TClipboardMgr::AboutToLoseControl
  166.  
  167. //----------------------------------------------------------------------------------------
  168. // TClipboardMgr::AbsorbScrapStuff:
  169. //----------------------------------------------------------------------------------------
  170. #pragma segment MAApplicationRes
  171.  
  172. void TClipboardMgr::AbsorbScrapStuff()
  173. {
  174.     fOldScrapStuff = fNewScrapStuff;            // stash previous version, for later
  175.                                                 // change-checkage
  176.     fNewScrapStuff = *(InfoScrap());            // Copy over from low memory to our
  177.                                                 // private global record
  178. } // TClipboardMgr::AbsorbScrapStuff
  179.  
  180. //----------------------------------------------------------------------------------------
  181. // TClipboardMgr::CheckDeskScrap:
  182. //----------------------------------------------------------------------------------------
  183. #pragma segment MAApplicationRes
  184.  
  185. void TClipboardMgr::CheckDeskScrap()
  186. {
  187.     OSErr err;
  188.  
  189.     this->AbsorbScrapStuff();
  190.  
  191.     if (fOldScrapStuff.scrapCount != fNewScrapStuff.scrapCount)
  192.     {
  193.         this->Changed(mScrapChanged,this);
  194.         
  195.         fClipView->FreeFromClipboard();            // AbandonCurrentClipboard 
  196.         fClipView = NULL;                        // no reason to have an Undo clipboard 
  197.  
  198.         // If the scrap is in memory and we are low on memory, then write
  199.         // the scrap to disk.
  200.         if ((fNewScrapStuff.scrapState > 0) && MemSpaceIsLow())
  201.             err = (OSErr)UnloadScrap();            // Write the scrap to disk.
  202.         
  203.         this->ReadFromDeskScrap();
  204.     }
  205. } // TClipboardMgr::CheckDeskScrap
  206.  
  207. //----------------------------------------------------------------------------------------
  208. // TClipboardMgr::GetDataToPaste:
  209. //----------------------------------------------------------------------------------------
  210. #pragma segment MAClipboard
  211.  
  212. long TClipboardMgr::GetDataToPaste(Handle aDataHandle,
  213.                                           ResType& dataType)
  214. {
  215.     long length;
  216.  
  217.     if (fGotClipType)
  218.     {
  219.         dataType = fPrefClipType;
  220.         length = fClipView->GivePasteData(aDataHandle, dataType);
  221.         if (length < 0)
  222.             Failure((OSErr)length, 0);
  223.     }
  224.     else
  225.     {
  226.         length = -1;
  227.         
  228. #if qDebugMsg
  229.         ProgramBreak("GetDataToPaste called when fGotClipType was false");
  230. #endif
  231.     }
  232.  
  233.     return length;
  234. } // TClipboardMgr::GetDataToPaste
  235.  
  236. //----------------------------------------------------------------------------------------
  237. // TClipboardMgr::Launch:
  238. //----------------------------------------------------------------------------------------
  239. #pragma segment MAInit
  240.  
  241. void TClipboardMgr::Launch()
  242. {
  243.     // Create the clip window and default view 
  244.     FailNIL(fClipWindow = this->MakeClipboardWindow());
  245.     fClipOrphanage = fClipWindow->FindSubView(kIDClipView);
  246.     FailNonObject(fClipOrphanage);
  247.  
  248.     // Add the clipboard manager as an application behavior
  249.     gDispatcher->AddBehavior(this);
  250.  
  251.     this->AbsorbScrapStuff();
  252.     this->ReadFromDeskScrap();
  253. } // TClipboardMgr::Launch
  254.  
  255. //----------------------------------------------------------------------------------------
  256. // TClipboardMgr::MakeClipboardWindow:
  257. //----------------------------------------------------------------------------------------
  258. #pragma segment MAInit
  259.  
  260. TWindow* TClipboardMgr::MakeClipboardWindow()
  261. {
  262.     TWindow * aWindow;
  263.  
  264.     if (qTemplateViews)
  265.     {
  266.         aWindow = gViewServer->NewTemplateWindow(kIDClipWindow, NULL);
  267.     }
  268.     else
  269.     {
  270.         TDeskScrapView * aDeskScrapView;
  271.  
  272.         aDeskScrapView = new TDeskScrapView;
  273.         aDeskScrapView->IDeskScrapView();
  274.         aDeskScrapView->fIdentifier = kIDClipView;
  275.         aWindow = gViewServer->NewSimpleWindow(kIDClipWindow, TRUE, TRUE, NULL, aDeskScrapView);
  276.     }
  277.     
  278.     if (aWindow)
  279.     {
  280.         aWindow->fHideOnSuspend = TRUE;
  281.         aWindow->fHandlesCursor = FALSE;
  282.         aWindow->fLetsSubViewsHandleCursor = FALSE;
  283.     }
  284.     return aWindow;
  285. } // TClipboardMgr::MakeClipboardWindow
  286.  
  287. //----------------------------------------------------------------------------------------
  288. // TClipboardMgr::ReadFromDeskScrap:
  289. //----------------------------------------------------------------------------------------
  290. #pragma segment MAClipboard
  291.  
  292. void TClipboardMgr::ReadFromDeskScrap()
  293. {
  294.     MAVolatile(TView*, aViewForClipboard);
  295.  
  296.     FailInfo fi;
  297.     Try(fi)
  298.     {
  299.         aViewForClipboard = this->MakeViewForAlienClipboard();
  300.         fi.Success();
  301.     }
  302.     else    // Recover
  303.     {
  304.         aViewForClipboard = fClipOrphanage;
  305.         if (fi.message == 0)
  306.             fi.message = messageImportClipFailed;
  307.         if (gDispatcher)
  308.             gDispatcher->ShowError(fi.error, fi.message);
  309.     }
  310.  
  311.     this->SetClipView(aViewForClipboard,NULL);
  312.     fClipWrittenToDeskScrap = TRUE;    // We're in synch with the scrap
  313. } // TClipboardMgr::ReadFromDeskScrap
  314.  
  315. //----------------------------------------------------------------------------------------
  316. // TClipboardMgr::MakeViewForAlienClipboard:
  317. //----------------------------------------------------------------------------------------
  318. #pragma segment MAClipboard
  319.  
  320. TView* TClipboardMgr::MakeViewForAlienClipboard()
  321. {
  322.     TView * aView;
  323.  
  324.     aView = gDispatcher->MakeViewForAlienClipboard();
  325.     if (!aView)
  326.         aView = fClipOrphanage;
  327.  
  328.     FailNonObject(aView);
  329.     return aView;
  330. } // TClipboardMgr::MakeViewForAlienClipboard
  331.  
  332. //----------------------------------------------------------------------------------------
  333. // TClipboardMgr::RegainControl:
  334. //----------------------------------------------------------------------------------------
  335. #pragma segment MAApplicationRes
  336.  
  337. void TClipboardMgr::RegainControl(Boolean checkClipboard)
  338. {
  339.     if (checkClipboard)
  340.         this->CheckDeskScrap();
  341. } // TClipboardMgr::RegainControl
  342.  
  343. //----------------------------------------------------------------------------------------
  344. // TClipboardMgr::SetClipView:
  345. //----------------------------------------------------------------------------------------
  346. #pragma segment MAClipboard
  347.  
  348. void TClipboardMgr::SetClipView(TView* clipView, TCommandHandler* itsContext)
  349. {
  350.     if (clipView)
  351.     {
  352.         if (fClipWindow)
  353.         {
  354.             // get the old clip window scroller if possible
  355.             TView * theSuperView;
  356.     
  357.             if (fClipWindow->HasSubViews())
  358.                 theSuperView = fClipWindow->FirstSubView();
  359.             else
  360.                 theSuperView = fClipWindow;
  361.                 
  362.             // throw out any views contained in the scroller (or window)
  363.             TView* theSubView;
  364.             while ((theSubView = theSuperView->FirstSubView()) != NULL)
  365.             {
  366.                 theSubView->ForceRedraw();
  367.                 theSuperView->RemoveSubView(theSubView);
  368.                 if (fClipWindow->IsShown())
  369.                     theSubView->Close();
  370.             }
  371.     
  372.             // pop in the new clipview
  373.             theSuperView->AddSubView(clipView);
  374.             if (fClipWindow->IsShown())
  375.                 clipView->Open();
  376.     
  377.             clipView->AdjustFrame();
  378.             clipView->RevealTop(kDontRedraw);
  379.             clipView->ForceRedraw();
  380.     
  381.             fClipWindow->SetWindowTarget(fClipWindow);
  382.             fClipWrittenToDeskScrap = clipView == fClipOrphanage;
  383.         }
  384. #if qDebug
  385.         else
  386.         {
  387.             ProgramBreak("SetClipView in absence of fClipWindow");
  388.         }
  389. #endif
  390.  
  391.         clipView->SetEnable(FALSE);                    // Ignore clicks while in clipboard views
  392.         this->Changed(mClipViewChanged, this);
  393.         fClipView = clipView;
  394.         fClipContext = itsContext;
  395.         
  396.         if (clipView->fDocument)
  397.             clipView->fDocument->SetIsGhostDocument(TRUE);
  398.     }
  399. #if qDebug
  400.     else
  401.     {
  402.         ProgramBreak("SetClipView: Attempt to set NULL clipView.");
  403.     }
  404. #endif
  405. } // TClipboardMgr::SetClipView
  406.  
  407. //----------------------------------------------------------------------------------------
  408. // TClipboardMgr::DoSetupMenus:
  409. //----------------------------------------------------------------------------------------
  410. #pragma segment MAApplicationRes
  411.  
  412. void TClipboardMgr::DoSetupMenus()
  413. {
  414.     Inherited::DoSetupMenus();
  415.  
  416.     Enable(cShowClipboard, TRUE);
  417.  
  418.     SetMenuState(cShowClipboard, kIDBuzzString, bzShowClip, bzHideClip, fClipWindow == gDispatcher->GetActiveWindow(kNoFloaters));
  419.  
  420. } // TClipboardMgr::DoSetupMenus
  421.  
  422. //----------------------------------------------------------------------------------------
  423. // TClipboardMgr::CanPaste:
  424. //----------------------------------------------------------------------------------------
  425. #pragma segment MAApplicationRes
  426.  
  427. void TClipboardMgr::CanPaste(ResType aClipType)
  428. {
  429.     if (fClipView && !fGotClipType)
  430.         if (fClipView->ContainsClipType(aClipType))
  431.         {
  432.             fGotClipType = TRUE;
  433.             fPrefClipType = aClipType;
  434.         }
  435.  
  436.     if (!gDispatcher->fSysWindowActive)
  437.         Enable(cPaste, fGotClipType);
  438. } // TClipboardMgr::CanPaste
  439.  
  440. //----------------------------------------------------------------------------------------
  441. // TClipboardMgr::DoMenuCommand:
  442. //----------------------------------------------------------------------------------------
  443. #pragma segment MASelCommand
  444.  
  445. void TClipboardMgr::DoMenuCommand(CommandNumber aCommandNumber)
  446. {
  447.     switch (aCommandNumber)
  448.     {
  449.         case cShowClipboard:
  450.             if (fClipWindow == gDispatcher->GetActiveWindow(kNoFloaters))
  451.                 fClipWindow->CloseAndFree();    // Hide the clipboard 
  452.             else
  453.             {
  454.                 fClipWindow->Open();
  455.                 fClipWindow->Select();
  456.             }
  457.             break;
  458.         default:
  459.             Inherited::DoMenuCommand(aCommandNumber);
  460.             break;
  461.     }
  462. } // TClipboardMgr::DoMenuCommand
  463.  
  464. //----------------------------------------------------------------------------------------
  465. // TClipboardMgr::Close:
  466. //----------------------------------------------------------------------------------------
  467. #pragma segment MATerminate
  468.  
  469. void TClipboardMgr::Close()
  470. {
  471.     LoadScrap();
  472. } // TClipboardMgr::Close
  473.  
  474. //----------------------------------------------------------------------------------------
  475. // TClipboardMgr::PutDeskScrapData:
  476. //----------------------------------------------------------------------------------------
  477. #pragma segment MAApplicationRes
  478.  
  479. OSErr TClipboardMgr::PutDeskScrapData(ResType aResType,
  480.                                              Handle aDataHandle)
  481. {
  482.     SignedByte savedState = LockHandle(aDataHandle);
  483.     long err = PutScrap(GetHandleSize(aDataHandle), aResType, (*aDataHandle));
  484.     HSetState(aDataHandle, savedState);
  485. #if qDebugMsg
  486.     if (err != noErr)
  487.         fprintf(stderr,"Error from PutScrap is: %d\n", err);
  488. #endif
  489.     return err;
  490. } // TClipboardMgr::PutDeskScrapData
  491.  
  492.  
  493. //========================================================================================
  494. // GLOBAL Procedures
  495. //========================================================================================
  496. #undef Inherited
  497.  
  498. //----------------------------------------------------------------------------------------
  499. // InitUClipboardMgr:
  500. //----------------------------------------------------------------------------------------
  501. #pragma segment MAInit
  502.  
  503. void InitUClipboardMgr()
  504. {
  505.     TClipboardMgr * aClipboardMgr;
  506.  
  507.     aClipboardMgr = new TClipboardMgr;
  508.     aClipboardMgr->IClipboardMgr();
  509.  
  510. #if qTemplateViews
  511.     MA_REGISTER_CLASS(TDeskScrapView);
  512. #endif
  513.  
  514. } // InitUClipboardMgr
  515.  
  516. //----------------------------------------------------------------------------------------
  517. // End of UClipboardMgr.cp
  518.  
  519. #pragma segment Inline
  520.